package org.ne.springboot.utils.PaperHandleUtils.PaperContentCheckUtils;


import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.web.multipart.MultipartFile;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import java.io.IOException;
import java.math.BigInteger;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import org.apache.poi.xwpf.usermodel.XWPFTableCell.XWPFVertAlign;


/**
 * @author wey
 * @date 2025/8/27 下午8:55 08
 * 语法检测/用户提问检测报告生成器
 **/
public  class ReportGenerateUtils {

    /**
     * @author wey
     * @param file 用户文档
     * @param lines 用户文档处理后数据
     * @param response 用户响应
     *
     * */
    public void generatePaperCheckReport(HttpServletResponse response, List<Map<String, Object>> lines, MultipartFile file) {

        try {
            // 1. 创建Word文档
            XWPFDocument document = new XWPFDocument();

            // 2. 添加报告标题
            addTitle(document);

            // 3. 添加文档信息概览
            addDocumentInfo(document, file);

            // 4. 添加统计信息
            addStatistics(document, lines);

            // 5. 添加详细检查结果
            addDetailedResults(document, lines);

            // 6. 添加总结和建议
            addSummaryAndRecommendations(document, lines);
            response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
            response.setHeader("content-Disposition", "attachment;filename=\"" + URLEncoder.encode("用户提问检查报告.docx", StandardCharsets.UTF_8) + "\"");
            document.write(response.getOutputStream());
            document.close();

        } catch (Exception e) {
            throw new RuntimeException("生成报告失败: " + e.getMessage(), e);
        }
    }



    // 添加报告标题
    private void addTitle(XWPFDocument document) {
        XWPFParagraph titleParagraph = document.createParagraph();
        titleParagraph.setAlignment(ParagraphAlignment.CENTER);
        // 设置段后间距
        titleParagraph.setSpacingAfter(400);

        XWPFRun titleRun = titleParagraph.createRun();
        titleRun.setText("文档检查报告");
        titleRun.setBold(true);
        titleRun.setFontSize(20);
        titleRun.setFontFamily("微软雅黑");
        titleRun.setColor("2E74B5");
    }

    // 添加文档信息概览
    private void addDocumentInfo(XWPFDocument document, MultipartFile file) {
        XWPFParagraph infoParagraph = document.createParagraph();
        infoParagraph.setSpacingAfter(200);

        XWPFRun infoRun = infoParagraph.createRun();
        infoRun.setText("文档名称: " + file.getOriginalFilename());
        infoRun.setFontSize(12);
        infoRun.setFontFamily("宋体");

        // 添加时间信息
        XWPFParagraph timeParagraph = document.createParagraph();
        XWPFRun timeRun = timeParagraph.createRun();
        timeRun.setText("检查时间: " + new java.util.Date().toString());
        timeRun.setFontSize(11);
        timeRun.setFontFamily("宋体");
        timeRun.setColor("666666");
    }

    // 添加统计信息
    private void addStatistics(XWPFDocument document, List<Map<String, Object>> lines) {
        XWPFParagraph statsParagraph = document.createParagraph();
        statsParagraph.setSpacingBefore(300);
        statsParagraph.setSpacingAfter(200);

        XWPFRun statsRun = statsParagraph.createRun();
        statsRun.setText("📊 检查统计");
        statsRun.setBold(true);
        statsRun.setFontSize(14);
        statsRun.setColor("44546A");

        // 计算统计信息
        long totalLines = lines.size();
        long errorFreeLines = lines.stream()
                .filter(line -> "无".equals(getContentValue(line, "有无语法错误")))
                .count();
        long errorLines = totalLines - errorFreeLines;

        // 创建统计表格
        XWPFTable statsTable = document.createTable(3, 2);
        statsTable.setWidth("100%");

        // 设置表格样式
        setTableHeader(statsTable.getRow(0), new String[]{"统计项", "数量"});
        setTableCell(statsTable.getRow(1), new String[]{"总检查段落", String.valueOf(totalLines)});
        setTableCell(statsTable.getRow(2), new String[]{"存在语法错误的段落", String.valueOf(errorLines)});
    }

    // 添加详细检查结果
    private void addDetailedResults(XWPFDocument document, List<Map<String, Object>> lines) {
        XWPFParagraph detailParagraph = document.createParagraph();
        detailParagraph.setSpacingBefore(400);

        XWPFRun detailRun = detailParagraph.createRun();
        detailRun.setText("🔍 详细检查结果");
        detailRun.setBold(true);
        detailRun.setFontSize(14);
        detailRun.setColor("44546A");

        for (int i = 0; i < lines.size(); i++) {
            Map<String, Object> line = lines.get(i);
            addSingleResult(document, line, i + 1);
        }
    }

    // 添加单个检查结果
    private void addSingleResult(XWPFDocument document, Map<String, Object> line, int index) {
        // 添加分隔线
        addSeparator(document);

        // 添加段落编号
        XWPFParagraph indexParagraph = document.createParagraph();
        XWPFRun indexRun = indexParagraph.createRun();
        indexRun.setText("段落 " + index);
        indexRun.setBold(true);
        indexRun.setFontSize(12);
        indexRun.setColor("2E74B5");

        // 添加原始文本
        XWPFParagraph originalParagraph = document.createParagraph();
        originalParagraph.setIndentationLeft(200);
        originalParagraph.setSpacingAfter(100);

        XWPFRun originalRun = originalParagraph.createRun();
        originalRun.setText("原始文本: " + line.get("original"));
        originalRun.setFontSize(11);
        originalRun.setFontFamily("宋体");
        originalRun.setColor("333333");

        // 添加检查结果
        Map<String, Object> content = getContentMap(line);
        if (content != null) {
            String hasError = String.valueOf(content.get("有无语法错误"));

            if ("有".equals(hasError)) {
                addErrorResult(document, content);
            } else {
                addSuccessResult(document, content);
            }
        }
    }

    // 添加错误结果
    private void addErrorResult(XWPFDocument document, Map<String, Object> content) {
        XWPFParagraph errorParagraph = document.createParagraph();
        errorParagraph.setIndentationLeft(200);

        XWPFRun errorRun = errorParagraph.createRun();
        errorRun.setText("❌ 存在语法错误");
        errorRun.setBold(true);
        errorRun.setFontSize(11);
        errorRun.setColor("FF0000");

        // 添加错误详情表格
        XWPFTable errorTable = document.createTable(4, 2);
        errorTable.setWidth("90%");

        setTableCell(errorTable.getRow(0), new String[]{"错误类型", String.valueOf(content.get("语法错误类型"))});
        setTableCell(errorTable.getRow(1), new String[]{"错误位置", String.valueOf(content.get("语法错误位置"))});
        setTableCell(errorTable.getRow(2), new String[]{"修改建议", String.valueOf(content.get("内容修改建议"))});
        setTableCell(errorTable.getRow(3), new String[]{"改进文本", String.valueOf(content.get("改进完整文本"))});
    }

    // 添加成功结果
    private void addSuccessResult(XWPFDocument document, Map<String, Object> content) {
        XWPFParagraph successParagraph = document.createParagraph();
        successParagraph.setIndentationLeft(200);

        XWPFRun successRun = successParagraph.createRun();
        successRun.setText("✅ 语法正确");
        successRun.setBold(true);
        successRun.setFontSize(11);
        successRun.setColor("00B050");

        XWPFParagraph detailParagraph = document.createParagraph();
        detailParagraph.setIndentationLeft(200);

        XWPFRun detailRun = detailParagraph.createRun();
        detailRun.setText("检查说明: " + String.valueOf(content.get("问题解决方法")));
        detailRun.setFontSize(11);
        detailRun.setFontFamily("宋体");
        detailRun.setColor("666666");
    }

    // 添加总结和建议
    private void addSummaryAndRecommendations(XWPFDocument document, List<Map<String, Object>> lines) {
        XWPFParagraph summaryParagraph = document.createParagraph();
        summaryParagraph.setSpacingBefore(400);

        XWPFRun summaryRun = summaryParagraph.createRun();
        summaryRun.setText("📝 总结与建议");
        summaryRun.setBold(true);
        summaryRun.setFontSize(14);
        summaryRun.setColor("44546A");

        // 计算整体评分
        long errorCount = lines.stream()
                .filter(line -> "有".equals(getContentValue(line, "有无语法错误")))
                .count();
        double score = 100 - (errorCount * 100.0 / lines.size());

        XWPFParagraph scoreParagraph = document.createParagraph();
        XWPFRun scoreRun = scoreParagraph.createRun();
        scoreRun.setText(String.format("文档整体语法评分: %.1f/100", score));
        scoreRun.setBold(true);
        scoreRun.setFontSize(12);
        scoreRun.setColor(score >= 80 ? "00B050" : score >= 60 ? "FFC000" : "FF0000");

        // 添加建议
        XWPFParagraph adviceParagraph = document.createParagraph();
        adviceParagraph.setSpacingBefore(200);

        XWPFRun adviceRun = adviceParagraph.createRun();
        adviceRun.setText("💡 改进建议:");
        adviceRun.setBold(true);
        adviceRun.setFontSize(12);

        if (errorCount == 0) {
            XWPFParagraph congratsParagraph = document.createParagraph();
            XWPFRun congratsRun = congratsParagraph.createRun();
            congratsRun.setText("恭喜！您的文档语法质量优秀，继续保持！");
            congratsRun.setFontSize(11);
            congratsRun.setColor("00B050");
        } else {
            XWPFParagraph tipsParagraph = document.createParagraph();
            XWPFRun tipsRun = tipsParagraph.createRun();
            tipsRun.setText("建议重点关注标记为错误的段落，按照建议进行修改。");
            tipsRun.setFontSize(11);
            tipsRun.setColor("FF0000");
        }
    }

    // 辅助方法
    private String getContentValue(Map<String, Object> line, String key) {
        Map<String, Object> content = getContentMap(line);
        return content != null ? String.valueOf(content.get(key)) : "";
    }

    private Map<String, Object> getContentMap(Map<String, Object> line) {
        try {
            Map<String, Object> result = (Map<String, Object>) line.get("result");
            Map<String, Object> answer = (Map<String, Object>) result.get("answer");
            return (Map<String, Object>) answer.get("content");
        } catch (Exception e) {
            return null;
        }
    }

    private void setTableHeader(XWPFTableRow row, String[] values) {
        for (int i = 0; i < values.length; i++) {
            XWPFTableCell cell = row.getCell(i);
            if (cell == null) {
                cell = row.addNewTableCell();
            }
            cell.setText(values[i]);

            // 设置表头样式
            for (XWPFParagraph paragraph : cell.getParagraphs()) {
                for (XWPFRun run : paragraph.getRuns()) {
                    run.setBold(true);
                    run.setColor("FFFFFF");
                }
            }
            cell.setColor("2E74B5"); // 设置背景色
        }
    }

    private void setTableCell(XWPFTableRow row, String[] values) {
        for (int i = 0; i < values.length; i++) {
            XWPFTableCell cell = row.getCell(i);
            if (cell == null) {
                cell = row.addNewTableCell();
            }
            cell.setText(values[i]);
        }
    }

    private void addSeparator(XWPFDocument document) {
        XWPFParagraph separatorParagraph = document.createParagraph();
        separatorParagraph.setSpacingBefore(200);
        separatorParagraph.setSpacingAfter(200);

        XWPFRun separatorRun = separatorParagraph.createRun();
        separatorRun.setText("—————————————————————————————————————————");
        separatorRun.setColor("DDDDDD");
        separatorRun.setFontSize(10);
    }

    public static XWPFDocument generationImageAndTableFormatReport(List<String> imageFormats, List<String> tableFormats) {
        try {
            XWPFDocument report = new XWPFDocument();

            //统计图片及表格检查结果
            int imageCount = imageFormats.size();
            int correctImageCount = 0;
            int issueImageCount = 0;
            int[] imageArr = new int[imageCount];
            for(int i = 0; i < imageCount; i++) {
                if (imageFormats.get(i).contains("图片标题正确")) {
                    imageArr[i] = 1;
                    correctImageCount++;
                }
            }
            issueImageCount = imageCount - correctImageCount;

            int tableCount = tableFormats.size();
            int correctTableCount = 0;
            int issueTableCount = 0;
            int[] tableArr = new int[tableCount];
            for(int i = 0; i <  tableCount; i++) {
                if (tableFormats.get(i).contains("表格标题正确")) {
                    tableArr[i] = 1;
                    correctTableCount++;
                }
            }
            issueTableCount = tableCount - correctTableCount;

            //添加标题
            XWPFParagraph titlePara = report.createParagraph();
            titlePara.setAlignment(ParagraphAlignment.CENTER);
            XWPFRun titleRun = titlePara.createRun();
            titleRun.setText("图片表格标注检查报告");
            titleRun.setFontFamily("微软雅黑");
            titleRun.setFontSize(16);
            titleRun.setBold(true);
            // 增加标题后的间距
            titlePara.setSpacingAfter(800);

            // 2. 添加“图片格式检查”部分
            addSectionHeader(report, "一、图片格式检查");
            addStatLine(report, "文档中图片总数", imageCount + " 张", "2C3E50");
            addStatLine(report, "符合要求的图片", correctImageCount + " 张", "27AE60"); // 绿色表示通过
            addStatLine(report, "不符合要求的图片",issueImageCount + " 张", "E74C3C"); // 红色表示问题

            // 3. 添加“表格格式检查”部分
            addSectionHeader(report, "二、表格格式检查");
            addStatLine(report, "文档中表格总数", tableCount + " 个", "2C3E50");
            addStatLine(report, "符合要求的表格", correctTableCount + " 个", "27AE60");
            addStatLine(report, "不符合要求的表格", issueTableCount + " 个", "E74C3C"); // 灰色表示无问题

            addSectionHeader(report, "三、检查结果");
            XWPFParagraph findingPara = report.createParagraph();
            XWPFRun findingRun = findingPara.createRun();
            findingRun.setBold(true);
            findingRun.setFontSize(12);
            findingRun.setFontFamily("微软雅黑");

            for(int i = 0; i < imageCount; i++) {
                addResultItem(report, imageArr[i] == 1 ? "通过" : "未通过", imageFormats.get(i));
            }

            for(int i = 0; i < tableCount; i++) {
                addResultItem(report, tableArr[i] == 1 ? "通过" : "未通过", tableFormats.get(i));
            }

            return  report;

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static void addSectionHeader(XWPFDocument doc, String headerText) {
        XWPFParagraph para = doc.createParagraph();
        para.setSpacingBefore(400); // 段前间距
        XWPFRun run = para.createRun();
        run.setText(headerText);
        run.setFontFamily("微软雅黑");
        run.setFontSize(13);
        run.setBold(true);
        run.setColor("1565C0"); // 蓝色标题

        // 添加底部边框
        para.setBorderBottom(Borders.SINGLE);
    }

    // 添加统计行（使用flex布局的模拟）
    private static void addStatLine(XWPFDocument doc, String label, String value, String color) {
        XWPFTable table = doc.createTable(1, 2);
        table.setWidth("100%");

        // 标签单元格
        XWPFTableCell labelCell = table.getRow(0).getCell(0);
        labelCell.setText(label);
        labelCell.setVerticalAlignment(XWPFVertAlign.CENTER);
        XWPFParagraph labelPara = labelCell.getParagraphs().get(0);
        labelPara.setAlignment(ParagraphAlignment.LEFT);
        labelPara.getRuns().get(0).setFontFamily("微软雅黑");
        labelPara.getRuns().get(0).setFontSize(11);

        // 值单元格
        XWPFTableCell valueCell = table.getRow(0).getCell(1);
        valueCell.setText(value);
        valueCell.setVerticalAlignment(XWPFVertAlign.CENTER);
        XWPFParagraph valuePara = valueCell.getParagraphs().get(0);
        valuePara.setAlignment(ParagraphAlignment.RIGHT);
        XWPFRun valueRun = valuePara.getRuns().get(0);
        valueRun.setFontFamily("微软雅黑");
        valueRun.setFontSize(11);
        valueRun.setColor(color);
        if (!"7F8C8D".equals(color)) { // 非灰色值加粗
            valueRun.setBold(true);
        }

        // 移除表格边框以实现极简外观
        table.setInsideHBorder(XWPFTable.XWPFBorderType.NONE, 0, 0, "FFFFFF");
        table.setInsideVBorder(XWPFTable.XWPFBorderType.NONE, 0, 0, "FFFFFF");
        table.setBottomBorder(XWPFTable.XWPFBorderType.NONE, 0, 0, "FFFFFF");
        table.setTopBorder(XWPFTable.XWPFBorderType.NONE, 0, 0, "FFFFFF");
        table.setLeftBorder(XWPFTable.XWPFBorderType.NONE, 0, 0, "FFFFFF");
        table.setRightBorder(XWPFTable.XWPFBorderType.NONE, 0, 0, "FFFFFF");
    }

    // 添加结果项
    private static void addResultItem(XWPFDocument doc, String status, String text) {
        XWPFParagraph para = doc.createParagraph();
        para.setSpacingBefore(100);
        para.setIndentationLeft(200); // 左缩进

        XWPFRun run = para.createRun();
        run.setFontSize(11);
        run.setFontFamily("微软雅黑");

        // 根据状态设置颜色
        if ("通过".equals(status)) {
            run.setColor("2E7D32"); // 绿色
        } else {
            run.setColor("C62828"); // 红色
        }

        run.setText(String.format("%s: %s", status, text));
    }

    public static void sendReport(HttpServletResponse response, XWPFDocument report) {
        response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode("图片表格标注检查报告.docx", StandardCharsets.UTF_8) + "\"");
        try {
            report.write(response.getOutputStream());
            report.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static XWPFDocument generationImageAndTableContentReport(List<String> imageContents, List<String> tableContents) {
        XWPFDocument doc = new XWPFDocument();

        /* 标题 */
        XWPFParagraph title = doc.createParagraph();
        title.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun r = title.createRun();
        r.setText("图片和表格内容检查报告");
        r.setFontSize(22);
        r.setBold(true);
        r.setFontFamily("微软雅黑");

        /* 图片章节 */
        createSection(doc, "一、图片内容检查", imageContents);

        /* 表格章节 */
        createSection(doc, "二、表格内容检查", tableContents);

        /* 总结 */
        XWPFParagraph sum = doc.createParagraph();
        sum.setSpacingBefore(300);
        XWPFRun sr = sum.createRun();
        sr.setText("三、总结");
        sr.setBold(true);
        sr.setFontSize(16);
        sr.setFontFamily("微软雅黑");

        String txt = """
                本次检查共涉及 %d 张图片和 %d 张表格，请按红色标注逐项修正。
                """.formatted(imageContents.size(), tableContents.size());
        XWPFParagraph p = doc.createParagraph();
        XWPFRun pr = p.createRun();
        pr.setText(txt);
        pr.setFontFamily("微软雅黑");
        pr.setFontSize(12);



        return doc;
    }

    private static void createSection(XWPFDocument doc, String sectionTitle, List<String> lines) {
        /* 节标题 */
        XWPFParagraph par = doc.createParagraph();
        par.setSpacingBefore(250);
        XWPFRun run = par.createRun();
        run.setText(sectionTitle);
        run.setBold(true);
        run.setFontSize(14);
        run.setFontFamily("宋体");

        /* 建表 */
        XWPFTable table = doc.createTable(lines.size() + 1, 5);
        setTableWidth(table, "10000");
        table.setTableAlignment(TableRowAlign.CENTER);

        /* 表头 */
        String[] heads = {"编号", "标题", "是否相符", "原因", "修改建议"};
        XWPFTableRow headRow = table.getRow(0);
        for (int i = 0; i < 5; i++) {
            XWPFTableCell cell = headRow.getCell(i);
            cell.setText(heads[i]);
            setCellColor(cell, "D9E2F3");
            setBold(cell);
        }

        /* 数据行 */
        for (int i = 0; i < lines.size(); i++) {
            String[] arr = lines.get(i).split("\\r?\\n|\\r"); // -1 保留空尾巴
            XWPFTableRow row = table.getRow(i + 1);

            for (int j = 0; j < 5; j++) {
                if (j == 0) {
                    row.getCell(j).setWidth("10%");
                }else if (j == 1) {
                    row.getCell(j).setWidth("14%");
                }else if(j == 2){
                    row.getCell(j).setWidth("13%");
                } else if (j == 3) {
                    row.getCell(j).setWidth("47%");
                }else {
                    row.getCell(j).setWidth("17%");
                }
                row.getCell(j).setVerticalAlignment(XWPFVertAlign.CENTER);
                row.getCell(j).setText(j < arr.length ? arr[j] : "");
            }
            /* 着色“是否相符”列 */
            applyConformStyle(row.getCell(2), arr.length > 2 ? arr[2] : "");
        }
    }

    private static void setTableWidth(XWPFTable table, String w) {
        CTTblPr pr = table.getCTTbl().getTblPr();
        CTTblWidth tblW = pr.isSetTblW() ? pr.getTblW() : pr.addNewTblW();
        tblW.setType(STTblWidth.DXA);
        tblW.setW(new BigInteger(w));
    }

    private static void setCellColor(XWPFTableCell cell, String rgb) {
        CTTcPr tcPr = cell.getCTTc().isSetTcPr() ? cell.getCTTc().getTcPr()
                                                 : cell.getCTTc().addNewTcPr();
        CTShd shd = tcPr.isSetShd() ? tcPr.getShd() : tcPr.addNewShd();
        shd.setFill(rgb);
    }

    private static void setBold(XWPFTableCell cell) {
        cell.getParagraphs().forEach(p -> p.getRuns().forEach(r -> r.setBold(true)));
    }

    private static void applyConformStyle(XWPFTableCell cell, String val) {
        String color = switch (val) {
            case "相符", "是"   -> "27AE60";
            case "不相符", "否" -> "E74C3C";
            default          -> "F39C12";
        };
        setCellColor(cell, color);
        cell.getParagraphs().forEach(p -> p.getRuns().forEach(r -> {
            r.setColor("FFFFFF");
            r.setBold(true);
        }));
    }
}